package com.mes.cloud.base.Aspect;

import com.mes.cloud.base.ServiceInfo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 对所有访问controller层的请求进行拦截记录
 * Created by Lenovo on 2017/10/18.
 */
@Aspect
@Component
public class WebLogAspect {
    private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    @Autowired
    ServiceInfo service;
    // 请求ip
    public String request_ip;
    // 请求方式 get/post
    public String request_method;
    // 请求url地址
    public String request_url;
    // 类方法
    public String class_method;
    // 请求结果
    public String request_result;
    // 请求参数
    public String request_params;

    public String request_ex;


    @Pointcut("execution(public * com.mes.cloud.*.controller..*.*(..))")
    public void webLog() {
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        clear();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        request_url = request.getRequestURL().toString();
        request_method = request.getMethod().toString();
        request_ip = request.getRemoteAddr();
        class_method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();

        try {
            Object args[] = joinPoint.getArgs();
            if (args != null) {
                Object objs[];
                objs = (Object[]) args.clone();
                for (int i = 0; i < objs.length; i++) {
                    Object obj = objs[i];
                    if (obj != null) {
                        String className = obj.getClass().getName();
                        if (className.equals("java.util.LinkedHashMap")) {
                            Map param = new HashMap();
                            param.putAll((LinkedHashMap) objs[i]);
                            if (param.containsKey("password")) {
                                param.put("password", "*********");
                                objs[i] = param;
                            }
                        }
                    }
                }
                request_params = Arrays.toString(objs);
            }
        } catch (Exception e) {
            request_params = Arrays.toString(joinPoint.getArgs());
        }
    }

    @AfterReturning(returning = "result", pointcut = "webLog()")
    public void doAfterReturning(Object result) throws Throwable {
        if (result != null) {
            request_result = result.toString();
            logger.info(String.format("%s %s [serverIP:%s] [appPort:%s] [requestIp:%s] [method:%s] [url:%s] [classMethod:%s] [params:%s] [result:%s] [exception:%s]"
                    , service.getApplicationName(), "ApiCommonLog", service.getIpAddress(), service.getPort(), request_ip, request_method, request_url, class_method, request_params, request_result, request_ex));
        }
    }

    @AfterThrowing(throwing = "ex", pointcut = "webLog()")
    public void throwss(Throwable ex) {
        logger.info(String.format("%s %s [serverIP:%s] [appPort:%s] [requestIp:%s] [method:%s] [url:%s] [classMethod:%s] [params:%s] [result:%s] [exception:%s]"
                , service.getApplicationName(), "ApiCommonLog", service.getIpAddress(), service.getPort(), request_ip, request_method, request_url, class_method, request_params, request_result, ex));
    }

    public void clear() {
        request_ip = "-";
        request_method = "-";
        request_url = "-";
        class_method = "-";
        request_result = "-";
        request_params = "-";
        request_ex = "-";
    }
}